package com.javafactroy.kunlong.bip.icp.message.data.base;

import com.javafactroy.kunlong.bip.icp.message.base.consts.AppEnum;
import lombok.Data;

import java.nio.ByteBuffer;

@Data
public class AppByteBuffer {
    ByteBuffer byteBuffer;
    AppPosition appPosition;

    AppEnum.AppTypeEnum appType;//data notice
    AppEnum.MsgTypeEnum msgType; //req rsp
    AppEnum.RespTypeEnum respType; //1 single 2 pageInfo

    public AppByteBuffer() {
        appPosition = new AppPosition();
    }

    public void init(byte[] bytes, AppEnum appEnum) {
        appPosition.setAppEnum(appEnum);
        setByteBuffer(ByteBuffer.wrap(bytes));

        getByteBuffer().rewind();
        setPosition(appEnum, 0, bytes.length - 1);
    }

    void setPosition(AppEnum appEnum, int start, int end) {
        if (appEnum.equals(AppEnum.header)) {
            appPosition.setHeaderStart(start);
            appPosition.setHeaderEnd(end);
        }
        if (appEnum.equals(AppEnum.body)) {
            appPosition.setBodyStart(start);
            appPosition.setBodyEnd(end);
        }
        if (appEnum.equals(AppEnum.page)) {
            appPosition.setPageInfoStart(start);
            appPosition.setPageInfoEnd(end);
        }
    }

    public void append(byte[] bytes, AppEnum appEnum) {
        appPosition.setAppEnum(AppEnum.all);
        ByteBuffer newByteBuffer = ByteBuffer.allocate(byteBuffer.capacity() + bytes.length);
        byteBuffer.rewind();
        newByteBuffer.put(byteBuffer.array());
        newByteBuffer.put(bytes);
        setPosition(appEnum, byteBuffer.capacity() + 1, byteBuffer.capacity() + bytes.length);
        byteBuffer = newByteBuffer;
        byteBuffer.rewind();
    }

    public void remove(int start, int len) {
        //  ByteBuffer newByteBuffer =ByteBuffer.allocate(byteBuffer.capacity()-len);
        /////  byteBuffer.rewind();
        //.byteBuffer=newByteBuffer;
    }

    ByteBuffer copy(int start, int end) {

        return ByteBuffer.wrap(byteBuffer.array(), start, end - start + 1);


    }

    void decode(AppMsg appMsg, AppEnum appObjectEnum) {
        if (AppEnum.header.equals(appObjectEnum)) {

            appMsg.getAppHeader().decode(this);
        }
        if (AppEnum.body.equals(appObjectEnum)) {

            appMsg.getAppBody().decode(this);
        }
        if (AppEnum.page.equals(appObjectEnum)) {

            appMsg.getAppResult().decode(this);
        }
    }

    void encode(AppMsg appMsg, AppEnum appObjectEnum) {
        if (AppEnum.header.equals(appObjectEnum)) {
            appMsg.getAppHeader().encode(this);
        }
        if (AppEnum.body.equals(appObjectEnum)) {

            appMsg.getAppBody().encode(this);
        }
        if (AppEnum.page.equals(appObjectEnum)) {

            appMsg.getAppResult().encode(this);
        }
    }

    @Data
    public class AppPosition {
        AppEnum appEnum;

        int headerStart = 0;
        int headerEnd; //header len
        //消息体 pos
        int bodyStart;
        int bodyEnd;
        //pageInfo
        //pageInfoHead
        int pageInfoStart;
        int pageInfoEnd;
        //fields pos;
        int fieldsDefStart;
        int fieldsDefEnd;
        //records pos
        int recordsStart;
        int recordsEnd;

        ByteBuffer copyHeader() {
            if (appPosition.getAppEnum().equals(AppEnum.header)) {
                return byteBuffer;
            }
            return copy(headerStart, headerEnd);
        }

        ByteBuffer copyBody() {
            if (appPosition.getAppEnum().equals(AppEnum.body)) {
                return byteBuffer;
            }
            return copy(bodyStart, bodyEnd);
        }

        ByteBuffer copyPageInfo() {
            if (appPosition.getAppEnum().equals(AppEnum.page)) {
                return byteBuffer;
            }
            return copy(pageInfoStart, pageInfoEnd);
        }
    }
}
